#include "DCMLicenseClient.h"

#pragma comment(lib, "Wbemuuid")

#include ".\licenseproxy\licenseproxy.h"
USING_LICENSE_PROXY;

CDCMLicenseClient::CDCMLicenseClient(void)
{
	m_pWbemServices = NULL;	
	m_nCPUID = 0;
	m_nBIOSID = 0;
	m_nMainBoardID = 0;
	m_nHardDiscID = 0;
	m_nUID = 0;
	m_nNICID = 0;

	m_CurAppType = CDCMLicense::kLicAppTypeNone;

}

CDCMLicenseClient::~CDCMLicenseClient(void)
{
}

BOOL CDCMLicenseClient::Activate(char* szActivationcode, DWORD HWinfoType)
{
	GetWMIInfo();   

	CDCMLicense::eLicenseAppType licAppType		= m_CurAppType;

	BOOL bSuccess = FALSE;

	CDCMLicense2 lic( licAppType, CDCMLicense::kLicTypeApp);
	CDCMLicense::SetApplication(m_CurAppType);
	unsigned __int64 opts = 0;;
	DWORD custId = 0;
	DWORD uid;
//	CUTILprod prod(HKEY_CLASSES_ROOT, LIC_REGISTRY);
	CUTILprod *prod = lic.GetUtilProd(m_CurAppType);
	CUTILprodinfo2 prodinfo;

	int res = 0;
	if((res = prod->TextToInfo(&prodinfo, &uid, szActivationcode)) >= 0)
	{

		switch( HWinfoType ) 
		{
//		case UNKNOWNSPEC:
//			bSuccess = FALSE;
//			break;
		case LicenseProxy::System:
			bSuccess = uid - m_nUID;
			break;
		case LicenseProxy::CPU:
			bSuccess = uid - m_nCPUID;
			break;
		case LicenseProxy::Disc:
			bSuccess = uid - m_nHardDiscID;
			break;
		case LicenseProxy::BIOS:
			bSuccess = uid - m_nBIOSID;
			break;
		case LicenseProxy::Mainboard:
			bSuccess = uid - m_nMainBoardID;
			break;
		case LicenseProxy::NIC:
			bSuccess = uid - m_nNICID;
			break;
		default:
			bSuccess = TRUE;
			break;
		}
	//	bSuccess = !bSuccess.
		switch ( bSuccess ) 
		{
		case FALSE:
			bSuccess = !(prod->SetInfo(&prodinfo, m_nUID ));
			break;
		case TRUE:
		default:
			bSuccess = FALSE;
			break;
		}
	}

	return bSuccess;
}

void CDCMLicenseClient::SetApplication(CDCMLicense::eLicenseAppType app)
{
//	CDCMLicense::SetApplication(app);
	m_CurAppType = app;

	CDCMLicense2 lic( m_CurAppType, CDCMLicense::kLicTypeApp);
	CDCMLicense::SetApplication(m_CurAppType);

	CUTILprod *pprod = lic.GetUtilProd(m_CurAppType);
//	CUTILprod2 prod(0, 0);
	m_nUID = pprod->GetUID();

	GetWMIInfo(); 
}

int CDCMLicenseClient::GetWMIInfo(void)
{
	if (m_nCPUID!=0 ) return 1;  //it's got already. 

	// TODO: Add your control notification handler code here
	CoInitialize(NULL);

	//Security needs to be initialized in XP first and this was the major problem 
	//why it was not working in XP.

//	if(
		CoInitializeSecurity( NULL,
							-1,
							NULL,
							NULL,
							RPC_C_AUTHN_LEVEL_PKT,
							RPC_C_IMP_LEVEL_IMPERSONATE,
							NULL,
							EOAC_NONE,
							0
							) ;
//	!= S_OK)
//		return -1;

	IWbemLocator * pIWbemLocator = NULL;
//	IWbemServices * pWbemServices = NULL;

	BSTR bstrNamespace = (L"root\\cimv2");


	if(CoCreateInstance (
            CLSID_WbemAdministrativeLocator,
            NULL ,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , 
            IID_IUnknown ,
            ( void ** ) & pIWbemLocator
            ) != S_OK)
				return -1;

	if(pIWbemLocator->ConnectServer(
                bstrNamespace,  // Namespace
                NULL,          // Userid
                NULL,           // PW
                NULL,           // Locale
                0,              // flags
                NULL,           // Authority
                NULL,           // Context
                &m_pWbemServices
                ) != S_OK)
				return -1;

	m_nCPUID = identifier( L"WIN32_Processor", L"ProcessorId");
	m_nBIOSID = identifier(L"Win32_BIOS", L"SerialNumber");
	m_nHardDiscID = identifier(L"Win32_DiskDrive", L"Signature");
	m_nMainBoardID = identifier(L"Win32_BaseBoard", L"SerialNumber");
	m_nNICID = identifier(L"Win32_NetworkAdapterConfiguration Where IPEnabled = True", L"MACAddress");

	pIWbemLocator->Release();
	m_pWbemServices->Release();
	CoUninitialize();

	return 0;
}


DWORD CDCMLicenseClient::identifier(BSTR wmiClass, BSTR wmiProperty)
{

	IEnumWbemClassObject * pEnumObject  = NULL;

	HRESULT hRes;
	CComBSTR strQuery = (L"Select * from ");
	strQuery += wmiClass;
	BSTR strQL = (L"WQL");
	hRes = m_pWbemServices->ExecQuery(strQL, strQuery,WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject);
	
	if(hRes != S_OK)
	{
//		MessageBox( _T("Could not execute Query")) ;
		return 0;
	}

	ULONG uCount = 1, uReturned;
	IWbemClassObject * pClassObject = NULL;


	hRes = pEnumObject->Reset();

	if(hRes != S_OK)
	{
//		MessageBox(_T("Could not Enumerate"));
		return 0;
	}

	hRes = pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
	if(hRes != S_OK)
	{
//		MessageBox( _T("Could not Enumerate"));
		return 0;
	}

	VARIANT v ;
	v.intVal = 0;

	BSTR strClassProp = wmiProperty;
	hRes = pClassObject->Get(strClassProp, 0, &v, 0, 0);
	if(hRes != S_OK)
	{
//		MessageBox(_T("Could not Get Value"));
		return 0;
	}

	DWORD hashvalue = 0;
	switch( v.vt ) 
	{
	case VT_I4:
		hashvalue = v.intVal;
		break;
	case VT_BSTR:
		{
			int len = lstrlenW( v.bstrVal );
			char *sz_KeyVal = new char[len+1];
			WideCharToMultiByte(CP_ACP,0,v.bstrVal, len,sz_KeyVal,len,NULL,NULL);
			sz_KeyVal[len]='\0';

			CUTILprod2 prod(0, NULL);
			hashvalue = prod.CheckSum2(sz_KeyVal, len);
			delete []sz_KeyVal;

		}
		break;
	default:
		break;
	}


	VariantClear( &v );

	pEnumObject->Release();
	pClassObject->Release();

	return hashvalue;

}
      
// hi,	 LIC_IPOD_BIT is 59
void CDCMLicenseClient::CheckLicense(int nLicID, ImLicenseChecking* pInterface)
{
	if (!pInterface ) return ; 

	ImLicenseChecking *pChecking = (ImLicenseChecking*) pInterface ;

	CDCMLicense2 lic( m_CurAppType, CDCMLicense::kLicTypeApp);
	CDCMLicense::SetApplication(m_CurAppType);
	unsigned __int64 opts = 1;
	opts<<=(nLicID-1); 

	int nres = (int) lic.CheckLicense( opts ) + ( rand()%10 ) ;
	switch( nres ) 
	{
	case 0: 
		pChecking->Do();
		break;
	case 1:
	case 2:
	case 3:
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
		CheckLicense( nLicID, pInterface );
		break;
	default: 
		pChecking->Pseudo();
		break;
	}

}

BOOL CDCMLicenseClient::Register(char* szRegcode, int *sn)
{
	CDCMLicense::eLicenseAppType licAppType		= m_CurAppType;

	BOOL bSuccess = FALSE;

	CDCMLicense2 lic( licAppType, CDCMLicense::kLicTypeApp);
	CDCMLicense::SetApplication(m_CurAppType);
	unsigned __int64 opts = 0;;
	DWORD custId = 0;
	DWORD uid;
	CUTILprod prod(HKEY_CLASSES_ROOT, LIC_REGISTRY);
	CUTILprodinfo2 prodinfo;

	int res = 0;
	if((res = prod.TextToInfo(&prodinfo, &uid, szRegcode)) >= 0)
	{
		*sn = prodinfo.option;
		return TRUE;
	};

	return FALSE;
}
